    //
//  HTTPRequest.m
//  WeClubs
//
//  Created by KevinWang on 17/6/14.
//  Copyright © 2017年 Zed. All rights reserved.
//

#import "HTTPRequest.h"
#import "AFNetworking.h"
#import "AFHTTPSessionManager+Config.h"
#import "MBProgressHUD+ZUtilities.h"
#import "HTTPRequest+SingleLogin.h"
#import "Reachability.h"
#import "ZFileCacheManager.h"
#import <QiniuSDK.h>
#import "ZLoginVC.h"
#import "ZNavigationController.h"

@implementation ZRequestModel

+ (ZRequestModel *)newWithTask:(id)task{
    ZRequestModel * model = [[ZRequestModel alloc]init];
    model.task = task;
    return  model;
}

- (BOOL)isFinish{
    NSURLSessionDataTask *task = self.task;
    return task.state == NSURLSessionTaskStateCompleted;
}

- (void)cancel{
    NSURLSessionDataTask *task = self.task;
    [task cancel];
}
@end

@interface HTTPRequest ()
/** 七牛云上传 */
@property (strong, nonatomic) QNUploadManager *upManager;
@property(nonatomic,strong) NSArray *todoItemTypes;

@end

@implementation HTTPRequest

#pragma mark - 单例
+(AFHTTPSessionManager *)requestManager{
    static AFHTTPSessionManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [AFHTTPSessionManager manager];
        
        [manager configSetting];
        
        
        manager.requestSerializer = [AFJSONRequestSerializer serializer];
        [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
        
        manager.responseSerializer = [AFJSONResponseSerializer serializer];
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"application/x-json",@"text/html", nil];
        
        manager.requestSerializer.HTTPShouldHandleCookies = YES;
    });
    
    //检测网络状态的改变
    [manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
                
                break;
            case AFNetworkReachabilityStatusNotReachable:
                
                break;
            case AFNetworkReachabilityStatusReachableViaWWAN:
                
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
                
                break;
            default:
                break;
        }
    }];
    
    //3.开始监听
    [manager.reachabilityManager startMonitoring];
    return manager;
    
}

+ (BOOL)isNetworkAvailable{
    Reachability *reach = [Reachability reachabilityForInternetConnection];
    NetworkStatus status = [reach currentReachabilityStatus];
    if (status == ReachableViaWiFi || status == ReachableViaWWAN) {
        return YES;
    }
    return NO;
}


#pragma mark - host管理
+(NSString *)InterfaceUrl:(NSString *)url{
    
    NSString *urlstring = [NSString stringWithFormat:@"%@/%@",RELEASE_BASE_URL,url];
    
    ZLog(@"urlstring:%@",urlstring);
    
    return urlstring;
    
}

#pragma mark - 网络请求
/*POST请求*/
+ (ZRequestModel *)POST:(NSString *)urlString parameter:(NSDictionary *)parameter  success:(requestSuccessCallBack)success failure:(requestErrorCallBack)failue{
    
    AFHTTPSessionManager *manager = [HTTPRequest requestManager];

    //配置公共参数
    parameter = [AFHTTPSessionManager configBaseParmars:parameter];
    [HTTPRequest setCookie];
    [HTTPRequest showActive];
    NSURLSessionDataTask *task = [manager POST:[self InterfaceUrl:urlString] parameters:parameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        
        int resultCode =[responseObject[@"result_code"] intValue];
        NSString *resultMsg = responseObject[@"result_msg"];
        
//        if (resultCode != ZNetManagerStatusSuccess) {
//            
//            NSError *error  = [NSError errorWithDomain:@"Login" code:resultCode userInfo:@{@"message":resultMsg}];
//            failue(error);
//        }
        
        switch (resultCode) {

            case ZNetManagerStatusTokenInvalidate:      // Token失效
            
            {
                // ========== 重置Token, 返回登陆界面 ==========
                [MBProgressHUD zAlertError:resultMsg];
                ZLoginVC *loginVC = [ZLoginVC zNew];
                ZNavigationController *mainVC = [[ZNavigationController alloc] initWithRootViewController:loginVC];
                [[UIApplication sharedApplication].keyWindow setRootViewController:mainVC];

                
            }
                break;
            case ZNetManagerStatusSuccess:
            {
                // ========== 请求成功, 执行Success代码块 ==========
              [HTTPRequest handelSuccessRequest:task responseObject:responseObject success:success fail:failue];
            }
                break;
            case ZNetManagerStatusPasswordError:    // 密码错误
            case ZNetManagerStatusUserNonExist:   // 找不到该用户
            case ZNetManagerStatusFail: // 请求失败
            case ZNetManagerStatusPermissionDenied: // 没有权限
            case ZNetManagerStatusAppError:
            {
                // Todo: 请求失败
                [MBProgressHUD zAlertHideHUD];
                [MBProgressHUD zAlertToastMessage:resultMsg];
            }
                break;
            case ZNetManagerStatusCallerInvalid:    // caller值违法
            case ZNetManagerStatusArgumentInvalid:  // 参数违法
            case ZNetManagerStatusArgumentEmpty:    // 请求参数为空
            case ZNetManagerStatusSignInvalid:      // 签名违法
            {
                ZLog(@"ZNetManager的网络请求参数配置出错, 请匹配错误参数信息: %zd", resultCode);
                [MBProgressHUD zAlertHideHUD];
                [MBProgressHUD zAlertToastMessage:resultMsg];
            }
                break;
            case ZNetManagerStatusAlertTips:    // 弹框需要确定且关闭当前页面tips
            {
                // Todo: 弹框需要确定且关闭当前页面
                [MBProgressHUD zAlertHideHUD];
                [MBProgressHUD zAlertToastMessage:resultMsg];
            }
                break;
            case ZNetManagerStatusToastTips:    // 弹框但不需要关闭页面tips
            {
                [MBProgressHUD zAlertHideHUD];
                [MBProgressHUD zAlertToastMessage:resultMsg];
            }
                break;
        }
        
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        @try {
            NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
            NSLog(@"dict =  %@",dict);
            NSMutableString *mtbStr = [[NSMutableString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"%@",mtbStr);
            [HTTPRequest handelFailRequest:task err:error fail:failue];
        } @catch (NSException *exception) {
            
            
        } @finally {
            [MBProgressHUD zAlertError:@"网路错误"];
        }
        
    }];
    
    ZRequestModel *requestModel = [ZRequestModel newWithTask:task];
    return requestModel;
}


// 图相上传  Todo: 待处理
+ (void)uploadImage:(UIImage *)image named:(NSString *)imageName success:(requestSuccessCallBack)success failure:(requestErrorCallBack)failue
{
    NSString *urlString = @"service/get_upload_token";
    NSDictionary *dataPara = @{};
    
    [self POST:urlString parameter:dataPara success:^(id resposeObject) {
        NSString *qiniuToken = [resposeObject[@"data"] objectForKey:@"token"];
        ZLog(@"七牛云上传Token : %@", qiniuToken);
        
        NSData *imageData = UIImagePNGRepresentation(image);
        QNUploadManager *upManager = [[[HTTPRequest alloc] init] upManager];
        [upManager putData:imageData key:imageName token:qiniuToken complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp)
         {
             NSString *domain = [ZFileCacheManager getValueLocalStoreForKey:kQiNiuDomainURLKey];
             NSString *avatarConfig = [ZFileCacheManager getValueLocalStoreForKey:kQiNiuAvatarConfigKey];
             ZLog(@"Resp: %@, Key: %@, domain:%@ avatarConfig: %@", resp, key, domain, avatarConfig);
             // 上传图片时, 图片设置名字则key为图片名, 没设置名字则七牛生成的图片名藏在resp当中
             NSString *name = imageName == nil ? [resp objectForKey:@"key"] : imageName;
             if (domain == nil|| name == nil || avatarConfig == nil ) {
                 failue(nil);
                 return ;
             }
             NSMutableString *fileName = [NSMutableString stringWithString:domain];
             [fileName appendString:name];
             [fileName appendString:avatarConfig];
             
             NSNumber *uploaded = info.error == nil ? @(1) : @(0);
             
             
             if (info.error) {
                 failue(info.error);
             }else{
                 success(fileName);
                 
             }
             NSDictionary *userInfo = @{
                                        ZNetManagerDidUploadImageNotificationURLKey : fileName,
                                        ZNetManagerDidUploadImageNotificationStateKey : uploaded,
                                        ZNetManagerDidUploadImageNotificationImageKey : image,
                                        ZNetManagerDidUploadImageNotificationImageNameKey : name,
                                        };
             [[NSNotificationCenter defaultCenter] postNotificationName:kDidUploadImageNotification object:nil userInfo:userInfo];
             
         } option:nil];
    } failure:^(NSError *error) {
        ZLog(@"获取七牛云Token失败!");
    }];
    
}


#pragma mark - 请求处理
+ (void)handelSuccessRequest:(NSURLSessionDataTask * _Nonnull)task responseObject:(id _Nullable)responseObject success:(requestSuccessCallBack)success fail:(requestErrorCallBack)fail{
    [HTTPRequest saveCookie];
    [HTTPRequest setCookie];
    [HTTPRequest hideActive];
    if (success) {
        success(responseObject);
    }
}

+ (void)handelFailRequest:(NSURLSessionDataTask * _Nonnull)task err:(NSError * _Nullable)err fail:(requestErrorCallBack)fail{
    [self hideActive];
    if (fail) {
        fail(err);
    }
}

#pragma mark - 获取七牛配置
+ (void)getQiniuConfig
{
    NSDictionary *param = @{};
    [self POST:kGetQiNiuConfigURL parameter:param success:^(id resposeObject) {
        NSDictionary *config = [resposeObject[@"data"] objectForKey:@"config"];
        NSString *picDomain = [config objectForKey:@"domain"];
        NSString *avatarConfig = [config objectForKey:@"avatar_config"];
        [ZFileCacheManager saveLocalStoreForValue:picDomain atKey:kQiNiuDomainURLKey];
        [ZFileCacheManager saveLocalStoreForValue:avatarConfig atKey:kQiNiuAvatarConfigKey];
    } failure:^(NSError *error) {
        
    }];
}

#pragma mark - 状态栏网络请求图标
+ (void)showActive {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}

+ (void)hideActive {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}


#pragma mark - saveCookie
+ (void)saveCookie{
    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL: [NSURL URLWithString:RELEASE_BASE_URL]];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:cookies];
    [HTTPRequest setCookie:data];
}

+ (void)setCookie{
    NSData *cookiesdata = [HTTPRequest getCookie];
    
    ZLog(@"--===Cookie===%@",cookiesdata);
    
    if([cookiesdata length]) {
        NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookiesdata];
        NSHTTPCookie *cookie;
        for (cookie in cookies) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        }
    }
    
}

+ (void)removeCookie{
    NSData *cookiesdata = [HTTPRequest getCookie];
    if([cookiesdata length]) {
        NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookiesdata];
        NSHTTPCookie *cookie;
        for (cookie in cookies) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
        }
    }
}

static NSString *kCookie = @"HHCookie";
+ (void )setCookie:(NSData *)cookie{
    if(cookie == nil){
        [[NSUserDefaults standardUserDefaults] removeObjectForKey:kCookie];
        [[NSUserDefaults standardUserDefaults] synchronize];
        return;
    }
    [[NSUserDefaults standardUserDefaults] setObject:cookie forKey:kCookie];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSData *)getCookie{
    return [[NSUserDefaults standardUserDefaults] objectForKey:kCookie];
}


#pragma mark - QiNiu
- (QNUploadManager *)upManager
{
    if (_upManager == nil) {
        QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) {
            builder.zone = [QNZone zone2];
        }];
        _upManager = [[QNUploadManager alloc] initWithConfiguration:config];
    }
    return _upManager;
}

- (NSArray<NSString *> *)todoItemTypes
{
    if (_todoItemTypes == nil) {
        _todoItemTypes = @[@"notify", @"mission", @"meeting"];
    }
    return _todoItemTypes;
}
@end
